package com.minimalist.common.entity.basic.po;

import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;

import java.io.Serial;
import java.io.Serializable;
import java.util.Objects;

/**
 * 租户数据源表实体类
 * <p>
 * 用于管理多租户环境下的数据源配置信息，
 * 包括数据源连接信息、认证信息等
 *
 * @author asus
 * @since 2025-02-14
 */
@Table(value = "m_tenant_datasource")
public class MTenantDatasource implements Serializable {
    
    @Serial
    private static final long serialVersionUID = 1L;

    // ========== 基本信息字段 ==========
    
    /**
     * ID自增
     */
    @Id(keyType = KeyType.Auto)
    private Long id;

    /**
     * 数据源ID
     */
    private Long datasourceId;

    /**
     * 租户ID
     */
    private Long tenantId;

    /**
     * 数据源名称
     */
    private String datasourceName;

    /**
     * 数据源连接
     */
    private String datasourceUrl;

    /**
     * 数据源用户名
     */
    private String username;

    /**
     * 数据源密码
     */
    private String password;

    // ========== 构造函数 ==========
    
    /**
     * 默认构造函数
     */
    public MTenantDatasource() {
    }

    /**
     * 全参数构造函数
     *
     * @param id             主键ID
     * @param datasourceId   数据源ID
     * @param tenantId       租户ID
     * @param datasourceName 数据源名称
     * @param datasourceUrl  数据源连接
     * @param username       数据源用户名
     * @param password       数据源密码
     */
    public MTenantDatasource(Long id, Long datasourceId, Long tenantId, String datasourceName,
                             String datasourceUrl, String username, String password) {
        this.id = id;
        this.datasourceId = datasourceId;
        this.tenantId = tenantId;
        this.datasourceName = datasourceName;
        this.datasourceUrl = datasourceUrl;
        this.username = username;
        this.password = password;
    }

    /**
     * 基本信息构造函数
     *
     * @param datasourceId   数据源ID
     * @param tenantId       租户ID
     * @param datasourceName 数据源名称
     * @param datasourceUrl  数据源连接
     */
    public MTenantDatasource(Long datasourceId, Long tenantId, String datasourceName, String datasourceUrl) {
        this.datasourceId = datasourceId;
        this.tenantId = tenantId;
        this.datasourceName = datasourceName;
        this.datasourceUrl = datasourceUrl;
    }

    // ========== Getter 和 Setter 方法 ==========
    
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getDatasourceId() {
        return datasourceId;
    }

    public void setDatasourceId(Long datasourceId) {
        this.datasourceId = datasourceId;
    }

    public Long getTenantId() {
        return tenantId;
    }

    public void setTenantId(Long tenantId) {
        this.tenantId = tenantId;
    }

    public String getDatasourceName() {
        return datasourceName;
    }

    public void setDatasourceName(String datasourceName) {
        this.datasourceName = datasourceName;
    }

    public String getDatasourceUrl() {
        return datasourceUrl;
    }

    public void setDatasourceUrl(String datasourceUrl) {
        this.datasourceUrl = datasourceUrl;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    // ========== Object 方法重写 ==========
    
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        
        MTenantDatasource that = (MTenantDatasource) o;
        
        return Objects.equals(id, that.id) &&
               Objects.equals(datasourceId, that.datasourceId) &&
               Objects.equals(tenantId, that.tenantId) &&
               Objects.equals(datasourceName, that.datasourceName) &&
               Objects.equals(datasourceUrl, that.datasourceUrl) &&
               Objects.equals(username, that.username) &&
               Objects.equals(password, that.password);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, datasourceId, tenantId, datasourceName, 
                           datasourceUrl, username, password);
    }

    @Override
    public String toString() {
        return "MTenantDatasource{" +
               "id=" + id +
               ", datasourceId=" + datasourceId +
               ", tenantId=" + tenantId +
               ", datasourceName='" + datasourceName + '\'' +
               ", datasourceUrl='" + datasourceUrl + '\'' +
               ", username='" + username + '\'' +
               ", password='[PROTECTED]'" +
               '}';
    }

    // ========== Builder 模式 ==========
    
    /**
     * 创建Builder实例
     *
     * @return MTenantDatasourceBuilder实例
     */
    public static MTenantDatasourceBuilder builder() {
        return new MTenantDatasourceBuilder();
    }

    /**
     * MTenantDatasource建造者类
     */
    public static class MTenantDatasourceBuilder {
        private Long id;
        private Long datasourceId;
        private Long tenantId;
        private String datasourceName;
        private String datasourceUrl;
        private String username;
        private String password;

        MTenantDatasourceBuilder() {
        }

        public MTenantDatasourceBuilder id(Long id) {
            this.id = id;
            return this;
        }

        public MTenantDatasourceBuilder datasourceId(Long datasourceId) {
            this.datasourceId = datasourceId;
            return this;
        }

        public MTenantDatasourceBuilder tenantId(Long tenantId) {
            this.tenantId = tenantId;
            return this;
        }

        public MTenantDatasourceBuilder datasourceName(String datasourceName) {
            this.datasourceName = datasourceName;
            return this;
        }

        public MTenantDatasourceBuilder datasourceUrl(String datasourceUrl) {
            this.datasourceUrl = datasourceUrl;
            return this;
        }

        public MTenantDatasourceBuilder username(String username) {
            this.username = username;
            return this;
        }

        public MTenantDatasourceBuilder password(String password) {
            this.password = password;
            return this;
        }

        public MTenantDatasource build() {
            return new MTenantDatasource(id, datasourceId, tenantId, datasourceName,
                                        datasourceUrl, username, password);
        }
    }

    // ========== 便利方法 ==========
    
    /**
     * 检查数据源配置是否完整
     *
     * @return true如果配置完整，否则false
     */
    public boolean isConfigComplete() {
        return datasourceId != null && tenantId != null && 
               datasourceName != null && !datasourceName.trim().isEmpty() &&
               datasourceUrl != null && !datasourceUrl.trim().isEmpty();
    }

    /**
     * 检查是否有认证信息
     *
     * @return true如果有用户名和密码，否则false
     */
    public boolean hasCredentials() {
        return username != null && !username.trim().isEmpty() &&
               password != null && !password.trim().isEmpty();
    }

    /**
     * 检查数据源名称是否有效
     *
     * @return true如果名称有效，否则false
     */
    public boolean isNameValid() {
        return datasourceName != null && !datasourceName.trim().isEmpty();
    }

    /**
     * 检查数据源URL是否有效
     *
     * @return true如果URL有效，否则false
     */
    public boolean isUrlValid() {
        return datasourceUrl != null && !datasourceUrl.trim().isEmpty() &&
               (datasourceUrl.startsWith("jdbc:") || datasourceUrl.startsWith("http"));
    }

    /**
     * 清除敏感信息（密码）
     */
    public void clearSensitiveInfo() {
        this.password = null;
    }

    /**
     * 获取数据源类型（从URL中推断）
     *
     * @return 数据源类型字符串
     */
    public String getDatasourceType() {
        if (datasourceUrl == null || datasourceUrl.trim().isEmpty()) {
            return "UNKNOWN";
        }
        
        String url = datasourceUrl.toLowerCase();
        if (url.contains("mysql")) {
            return "MYSQL";
        } else if (url.contains("postgresql")) {
            return "POSTGRESQL";
        } else if (url.contains("oracle")) {
            return "ORACLE";
        } else if (url.contains("sqlserver")) {
            return "SQLSERVER";
        } else if (url.contains("h2")) {
            return "H2";
        } else {
            return "OTHER";
        }
    }

    /**
     * 复制实例（不包含敏感信息）
     *
     * @return 新的MTenantDatasource实例
     */
    public MTenantDatasource copyWithoutSensitiveInfo() {
        MTenantDatasource copy = new MTenantDatasource();
        copy.setId(this.id);
        copy.setDatasourceId(this.datasourceId);
        copy.setTenantId(this.tenantId);
        copy.setDatasourceName(this.datasourceName);
        copy.setDatasourceUrl(this.datasourceUrl);
        copy.setUsername(this.username);
        // 不复制密码
        return copy;
    }
}
